package com.fsd.admin.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.annotation.Resource;

import org.apache.log4j.Logger;

import com.google.gson.Gson;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.fsd.core.bean.CheckTree;
import com.fsd.core.bean.Tree;
import com.fsd.core.common.BusinessException;
import com.fsd.core.util.Config;
import com.fsd.core.util.ParametersUtil;
import com.fsd.admin.model.A_Employee;
import com.fsd.admin.model.I_bankinfo;
import com.fsd.admin.service.I_bankinfoService;
import com.fsd.admin.dao.I_bankinfoDao;

@Repository("i_bankinfoServiceImpl")
public class I_bankinfoServiceImpl extends MainServiceImpl<I_bankinfo, String> implements I_bankinfoService{
    
    private static final Logger log = Logger.getLogger(I_bankinfoServiceImpl.class);
    private String depict = "题库";
    
    @Resource(name = "i_bankinfoDaoImpl")
	public void setBaseDao(I_bankinfoDao I_bankinfoDao) {
		super.setBaseDao(I_bankinfoDao);
	}
	
	@Resource(name = "i_bankinfoDaoImpl")
	private I_bankinfoDao objectDao;
	
	private static final Lock lock = new ReentrantLock();
	
	/**
     * 知识库
     */
	public static final String fsdzsk1 = "FSDKNOWLEDGE";
	public static final String fsdzsk2 = "知识库";
	/**
	 * 题目库
	 */
	public static final String fsdtmk1 = "FSDQUESTIONS";
	public static final String fsdtmk2 = "题目库";
	/**
	 * 题卷库
	 */
	public static final String fsdtjk1 = "FSDLIBRARY";
	public static final String fsdtjk2 = "题卷库";
	/**
	 * 问卷库
	 */
	public static final String fsdwjk1 = "FSDINVESTIGATE";
	public static final String fsdwjk2 = "问卷库";
	/**
	 * 投票库
	 */
	public static final String fsdtpk1 = "FSDVOTE";
	public static final String fsdtpk2 = "投票库";
	
	/**
	 * 递归
	 */
	private void getObjectStruct(I_bankinfo object, List<I_bankinfo> objList){
		for (I_bankinfo obj : objList) {
			if(object.getId().equals(obj.getParentid())){
				object.getList().add(obj);
				if (!Boolean.valueOf(obj.getIsleaf()))
					this.getObjectStruct(obj, objList);
			}
		}
	}
	
	/**
	 * 获取栏目结构
	 * @param id
	 * @return
	 */
	private I_bankinfo getObjectStructByID(String id, String companyid) throws Exception{
		lock.lock();
		Map<String, I_bankinfo> objectMap = null;
		try {
				List<I_bankinfo> allObjectList = objectDao.queryByHql(
						"from I_bankinfo t where t.companyid in ('" + companyid + "','0') and t.deleted = '0' order by t.sort asc");
				objectMap = new HashMap<String, I_bankinfo>();
				List<I_bankinfo> objectList = new ArrayList<I_bankinfo>();
				List<I_bankinfo> objList = new ArrayList<I_bankinfo>();
				for (I_bankinfo obj : allObjectList) {
					objectMap.put(obj.getId(), obj);
 					if("0".equals(obj.getParentid())){
						objList.add(obj);
					}else{
						objectList.add(obj);
					}
				}
				for (I_bankinfo obj : objList) {
					this.getObjectStruct(obj, objectList);
				}
		}finally{
			lock.unlock();
		}
		if (objectMap != null && objectMap.containsKey(id))
			return objectMap.get(id);
		else
			return null;
	}
	
	private String checkLeaf(String fid){
		long num = objectDao.getCount("parentid = '"+ fid +"'", "deleted = '0'");
		if (num > 0)
			return "false";
		return "true";
	}
	
	private List<I_bankinfo> queryObjectListById(String fid, String companyid){
		return objectDao.queryByHql("from I_bankinfo a where a.companyid = '"+ companyid +"' and a.parentid = '"+ fid +"' and a.deleted = '0' order by sort asc");
	}
	
	/**
	 * 获取下级所属节点ID集合
	 * @return
	 */
	public List<String> getObjectChildIDList(String fid, A_Employee employee) throws Exception{
		I_bankinfo bankinfo = this.getObjectStructByID(fid, employee.getCompanyid());
		if (bankinfo == null || bankinfo.getList() == null || bankinfo.getList().size() == 0)
			return new ArrayList<String>();
		I_bankinfo obj = null;
		List<String> idList = new ArrayList<String>();
		this.getObjectChildIDList(bankinfo.getList(), idList);
		return idList;
	}
	private void getObjectChildIDList(List<Object> objList, List<String> idList){
		if (objList == null || objList.size() == 0)
			return;
		I_bankinfo obj = null;
		for (Object object : objList) {
			obj = (I_bankinfo) object;
			idList.add(obj.getId());
			this.getObjectChildIDList(obj.getList(), idList);
		}
	}
	
	/**
	 * 异步加载对象树
	 * @return
	 * @throws Exception
	 */
	public List<Tree> getAsyncObjectTree(String fid, A_Employee employee) throws Exception{
		I_bankinfo bankinfo = this.getObjectStructByID(fid, employee.getCompanyid());
		List<Tree> treelist = new ArrayList<Tree>();
		if (bankinfo != null && bankinfo.getList() != null && bankinfo.getList().size() > 0){
			Tree tree = null;
			I_bankinfo obj = null;
			for (Object o : bankinfo.getList()) {
				obj = (I_bankinfo)o;
				tree = new Tree();
				tree.setId(obj.getId());
				tree.setText(obj.getName());
				tree.setLeaf(Boolean.valueOf(obj.getIsleaf()));
				treelist.add(tree);
			}
		}
		return treelist;
	}
	
    /**
	 * 编辑对象
	 * @param obj
	 * @param employee
	 * @throws Exception
	 */
	public void save(I_bankinfo obj, A_Employee employee) throws Exception{
        if(obj.getId() != null && !"".equals(obj.getId())){
        	//修改
        	if (obj.getId() == obj.getParentid()){
    			throw new BusinessException(depict + "所属题库不得选择自己!");
        	}
            I_bankinfo old_obj = objectDao.get(obj.getId());
            String fid = old_obj.getParentid();
            
            old_obj.setUpdatedate(this.getData());//设置修改日期
			old_obj.setUpdateemployeeid(employee.getId());//设置修改用户id
			old_obj.setUpdateemployeename(employee.getRealname());//设置修改用户姓名
			old_obj.setParentid(obj.getParentid());
			old_obj.setParentname(obj.getParentname());
			old_obj.setName(obj.getName());
			old_obj.setSymbol(obj.getSymbol());
			old_obj.setDescription(obj.getDescription());
			old_obj.setSort(obj.getSort());
			//old_obj.setIsleaf(obj.getIsleaf());
			old_obj.setRemark(obj.getRemark());
			old_obj.setId(obj.getId());
            objectDao.update(old_obj);
            if (!fid.equals(obj.getParentid())){
				objectDao.executeHql("update I_bankinfo t set t.isleaf = '" + this.checkLeaf(obj.getParentid()) + "' where t.id = '" + obj.getParentid() + "'");
				objectDao.executeHql("update I_bankinfo t set t.isleaf = '" + this.checkLeaf(fid) + "' where t.id = '" + fid + "'");
			}
           
        }else{
            //添加
            obj.setId(this.getUUID());//设置主键
			obj.setCompanyid(employee.getCompanyid());//所属单位
			obj.setAdddate(this.getData());//设置添加日期
			obj.setAddemployeeid(employee.getId());//设置添加用户id
			obj.setAddemployeename(employee.getRealname());//设置添加用户姓名
			obj.setDeleted("0");//设置删除标志(0:正常 1：已删除)
			obj.setIsleaf("true");
			objectDao.save(obj);
			objectDao.executeHql("update I_bankinfo t set t.isleaf = 'false' where t.id = '" + obj.getParentid() + "'");
		}
		this.sysLogService.saveObject(Config.LOGTYPEBC, this.depict + obj.getId() + obj.getName(), employee, I_bankinfoServiceImpl.class);
    }
    
    
    /**
	 * 删除对象
	 * @param parameters
	 * @throws Exception
	 */
	public void delObject(ParametersUtil parameters, A_Employee employee) throws Exception{
		Gson gs = new Gson();
		Map objectMap = gs.fromJson(parameters.getJsonData(), Map.class);
		ArrayList<String> dir = (ArrayList<String>) objectMap.get("ids");
		String ids = this.getSQLinByIDList(dir);
		String oid = dir.get(0);
		objectDao.executeHql("update I_bankinfo t set t.deleted = '1', t.updatedate = '" + this.getData() + 
				"', t.updateemployeeid = '" + employee.getId() + "', t.updateemployeename = '" + employee.getRealname() + 
				"' where t.id in (" + ids + ")");
		I_bankinfo obj = objectDao.get(oid);
		if (obj != null){
			objectDao.executeHql("update I_bankinfo t set t.isleaf = '" + this.checkLeaf(obj.getParentid()) + "' where t.id = '" + obj.getParentid() + "'");
		}
		this.sysLogService.saveObject(Config.LOGTYPESC, this.depict + ids, employee, I_bankinfoServiceImpl.class);
	}
    
    /**
	 * 根据ID加载对象
	 * @param parameters
	 * @return
	 * @throws Exception
	 */
	public I_bankinfo getObjectById(ParametersUtil parameters) throws Exception{
		Gson gs = new Gson();
		Map objectMap = gs.fromJson(parameters.getJsonData(), Map.class);
		if(objectMap.get("id") == null && "".equals(objectMap.get("id"))){
			throw new BusinessException(depict + "获取缺少ID参数!");
		}
		I_bankinfo obj = objectDao.get(objectMap.get("id").toString());
		if(obj == null){
			throw new BusinessException(depict + "数据不存在!");
		}
		
		return obj;
	}

	/**
	 * 顺序排序
	 * @param parameters
	 */
	public void updateSortObject(ParametersUtil parameters) throws Exception{
		Gson gs = new Gson();
		Map objectMap = gs.fromJson(parameters.getJsonData(), Map.class);
		List<String> idList = (List<String>) objectMap.get("ids");
		String ids = this.getSQLinByIDList(idList);
		I_bankinfo objDW = objectDao.get(objectMap.get("id").toString());
		if (objDW == null)
			throw new BusinessException(depict + "获取定位对象为空!");
		List<I_bankinfo> objList = objectDao.queryByHql("from I_bankinfo t where " +
				"t.parentid = '" + objDW.getParentid() + "' and t.deleted = '0' " +
				"and t.id not in (" + ids + ") " +
				"and t.sort >= " + objDW.getSort() + " order by t.sort asc");
		long sort = objDW.getSort();
		for (String id : idList) {
			objectDao.executeHql("update I_bankinfo t set t.sort = " + sort + " where t.id = '" + id + "'");
			sort++;
		}
		for (I_bankinfo obj : objList) {
			objectDao.executeHql("update I_bankinfo t set t.sort = " + sort + " where t.id = '" + obj.getId() + "'");
			sort++;
		}
	}

	/**
	 * 加载分页数据
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public ParametersUtil getObjectPageList(ParametersUtil param, A_Employee employee) throws Exception{
		Criteria c = objectDao.createCriteria();
		c.add(Restrictions.eq("deleted", "0"));
		c.add(Restrictions.eq("companyid", employee.getCompanyid()));
		c.addOrder(Order.asc("sort"));
		if(param.getJsonData() != null && !"".equals(param.getJsonData())){
			Gson gs = new Gson();
			Map objectMap = gs.fromJson(param.getJsonData(), Map.class);
			if(objectMap.get("fid") != null && !"".equals(objectMap.get("fid"))){
				c.add(Restrictions.eq("parentid", objectMap.get("fid")));
			}
			if(objectMap.get("name") != null && !"".equals(objectMap.get("name"))){
				c.add(Restrictions.like("name", "%" + objectMap.get("name") + "%"));
			}
		}
		return objectDao.findPager(param , c);
	}
	
	/**
	 * 获得复选框权限结构
	 * @param isAdmin
	 * @param fTree
	 * @param list
	 */
	private void getCheckTreeStruct(CheckTree fTree, List<Object> list){
		fTree.setLeaf(true);
		if (list == null && list.size() == 0){
			return;
		}
		CheckTree tree = null;
		I_bankinfo obj = null;
		for (Object object : list) {
			obj = (I_bankinfo) object;
			fTree.setLeaf(false);
			tree = new CheckTree();
			tree.setChecked(false);
			tree.setId(obj.getId());
			tree.setText(obj.getName());
			tree.setLeaf(Boolean.valueOf(obj.getIsleaf()));
			this.getCheckTreeStruct(tree , obj.getList());
			fTree.getChildren().add(tree);
		}
	}
	
	/**
	 * 获取权限树
	 * @param user
	 * @return
	 */
	public List<CheckTree> getAllQxObjectCheck(ParametersUtil parameters, A_Employee employee) throws Exception{
		Gson gs = new Gson();
		Map objectMap = gs.fromJson(parameters.getJsonData(), Map.class);
		if(objectMap.get("id") == null && "".equals(objectMap.get("id"))){
			throw new BusinessException(depict + "获取缺少ID参数!");
		}

		List<CheckTree> menulist = new ArrayList<CheckTree>();
		List<Object> list = this.getObjectStructByID(
				objectMap.get("id").toString(), employee.getCompanyid()).getList();
		if (list == null || list.size() == 0)
			return menulist;
		CheckTree tree = null;
		I_bankinfo obj = null;
		for (Object object : list) {
			obj = (I_bankinfo) object;
			tree = new CheckTree();
			tree.setChecked(false);
			tree.setId(obj.getId());
			tree.setText(obj.getName());
			tree.setLeaf(Boolean.valueOf(obj.getIsleaf()));
			this.getCheckTreeStruct(tree, obj.getList());
			menulist.add(tree);
		}
		return menulist;
	}
	
	/**
	 * 获得复选框权限结构
	 * @param isAdmin
	 * @param fTree
	 * @param list
	 */
	private void getCheckTreeStruct(CheckTree fTree, List<Object> list, List<String> popdomList){
		fTree.setLeaf(true);
		if (list == null && list.size() == 0){
			return;
		}
		CheckTree tree = null;
		I_bankinfo obj = null;
		boolean flage = false;
		for (Object object : list) {
			obj = (I_bankinfo) object;
			flage = false;
			for (String pid : popdomList) {
				if (obj.getId().equals(pid)){
					flage = true;
					break;
				}
			}
			if (!flage)
				continue;
			fTree.setLeaf(false);
			tree = new CheckTree();
			tree.setChecked(false);
			tree.setId(obj.getId());
			tree.setText(obj.getName());
			tree.setLeaf(Boolean.valueOf(obj.getIsleaf()));
			this.getCheckTreeStruct(tree , obj.getList(), popdomList);
			fTree.getChildren().add(tree);
		}
	}
	
	/**
	 * 异步加载对象树
	 * @return
	 * @throws Exception
	 */
	public List<Tree> getAsyncObjectTreeByPopdom(String fid, A_Employee employee, Map<String, List<String>> popdomMap) throws Exception{
		if (employee.isIsadmin())
			return this.getAsyncObjectTree(fid, employee);
		//I_bankinfo
		List<String> bankInfoIds = popdomMap.get(Config.POPEDOMSUBJECT);
		bankInfoIds.addAll(popdomMap.get(Config.POPEDOMSUBJECTW));
		I_bankinfo bankInfo = this.getObjectStructByID(fid, employee.getCompanyid());
		List<Tree> treelist = new ArrayList<Tree>();
		if (bankInfo != null && bankInfo.getList() != null && bankInfo.getList().size() > 0){
			Tree tree = null;
			I_bankinfo obj = null;
			boolean flage = false;
			for (Object o : bankInfo.getList()) {
				obj = (I_bankinfo)o;
				flage = false;
				for (String sid : bankInfoIds) {
					if (obj.getId().equals(sid)){
						flage = true;
						break;
					}
				}
				if (!flage)
					continue;
				tree = new Tree();
				tree.setId(obj.getId());
				tree.setText(obj.getName());
				tree.setLeaf(Boolean.valueOf(obj.getIsleaf()));
				treelist.add(tree);
			}
		}
		return treelist;
	}
}
